package com.lzhan.day17;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

public class ProxyDemo {

	static interface IFoo {
		public void fun(int a, String name);
		public void fun(int a);
	}

	static class IFooImpl implements IFoo {
		@Override
		public void fun(int a, String name) {
			
			System.out.println("IFooImpl....");
		}

		@Override
		public void fun(int a) {
			System.out.println("only a");
		}
	}
	static class IFoobImpl implements IFoo {
		@Override
		public void fun(int a, String name) {
			System.out.println("bbbbbb....");
		}

		@Override
		public void fun(int a) {
			System.out.println("only a");
		}
	}
	static class MyHandler implements InvocationHandler {

		Object target;
//1，根据传入的第二个参数interfaces动态生成一个类，实现interfaces中的接口，该例中即IFOO接口的FUN方法。并且继承了Proxy类，重写了hashcode,toString,equals等三个方法。具体实现可参看 ProxyGenerator.generateProxyClass(...); 该例中生成了$Proxy0类

//2，通过传入的第一个参数classloder将刚生成的类加载到jvm中。即将$Proxy0类load

//3，利用第三个参数，调用$Proxy0的$Proxy0(InvocationHandler)构造函数 创建$Proxy0的对象，并且用interfaces参数遍历其所有接口的方法，并生成Method对象初始化对象的几个Method成员变量

//4，将$Proxy0的实例返回给客户端。

		public Object bind(Object target) {
			this.target = target;
			return Proxy.newProxyInstance(target.getClass().getClassLoader(),
					target.getClass().getInterfaces(), this);
		}

		// proxy:代理的对象IFoo
		// Method:你要调用的方法
		// args:调用Method实际传入的参数
		@Override
		public Object invoke(Object proxy, Method method, Object[] args)
				throws Throwable {
			// System.out.println(proxy.getClass().getName());//代理类
			System.out.println("执行方法前");
//			调用实现类的方法 
			Object result = method.invoke(target, args);
			
			System.out.println("执行方法后");
			return result;
		}

	}

	public static void main(String[] args) {
		// $Proxy0 implements IFoo{ fun(){ handler.invoke(
		// IFoo foo = (IFoo) Proxy.newProxyInstance(IFoo.class.getClassLoader(),
		// new Class[]{IFoo.class}, new MyHandler());
		// foo.fun(10,"ja");

		MyHandler mh = new MyHandler();
//		foo 是个代理者，他代理是new IFooImpl()对象的功能
		IFoo foo = (IFoo) mh.bind(new IFooImpl());
//		System.out.println("reslut"+foo.getClass().getName());
		foo.fun(10, "ja");
		foo.fun(10);
		
		
		
	}

}
